<template>
  <div>
    <div class="header">
      <el-checkbox style="margin: 0 17px" v-model="checkAll" />
      <div class="header-wrapper" :style="headerStyle">
        <div v-for="item in prop" :style="item.style" class="header-wrapper_item">
          {{ item.name }}
        </div>
      </div>
    </div>
    <div
      class="viewPort"
      ref="viewPort"
      :style="{ '--scroll-eight': rowHeight + 'px' }"
      @scroll="handleScroll">
      <div class="scrollBar" ref="scrollBar"></div>
      <div class="list" ref="list">
        <div class="row" ref="row" v-for="(item, index) in finalList" :key="index">
          <!-- 选择 -->
          <el-checkbox style="margin: 0 17px" v-model="listData[item.index].check" @change="checkBoxChange" />
          <!-- 表格选项 -->
          <div
            class="prop"
            :style="{
              ..._.style,
            }"
            v-for="_ in prop">
            <!-- 按钮相关 -->
            <span
              v-if="Array.isArray(_.prop)"
              style="display: flex; justify-content: center"
              :style="_.style">
              <el-button
                type="text"
                v-for="text in _.prop"
                @click="text.click(listData[item.index])"
                :disabled="text.disabled ? text.disabled(listData[item.index]) : false"
                style="margin: 0 3px"
                :style="text.style"
                v-hasPermi="text.permission">
                {{ text.name }}
              </el-button>

              <slot name="option"></slot>
            </span>
            <!-- 普通的显示字段 -->
            <span v-else>
              <!-- @click="text.click(listData[item.index])" -->
              <span
                :style="{
                  ...listData[item.index][_.prop + 'Style'],
                }">
                {{ listData[item.index][_.prop + 'Text'] || listData[item.index][_.prop] }}
              </span>
            </span>
          </div>
        </div>
      </div>
    </div>
    <div style="margin: 20px 0 0 20px;">共{{ listData.length }}条</div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      checkAll: false,
      startIndex: 0, // 开始索引默认为0
      endIndex: this.viewCount, // 结束索引为列表展示条数
    }
  },
  props: {
    prop: {
      type: Array,
      default: [],
    },
    showSelect: {
      type: Boolean,
      default: true,
    },
    // 行高
    rowHeight: {
      type: Number,
      default: 25,
    },
    // 显示条数
    viewCount: {
      type: Number,
      default: 20,
    },
    // 数据
    listData: {
      type: Array,
      required: true,
    },
  },
  watch: {
    checkAll: function (newV) {
      if (newV) {
        console.log(`newV checkAll==>`, newV)
        this.listData.forEach((i) => (i.check = true))
        this.emitRowSelect()
      } else {
        this.listData.forEach((i) => (i.check = false))
        this.emitRowSelect()
      }
    },
    listData: function (newV) {
      // console.log(`newV listData==>`, newV);
      this.updateHeight()
    },
  },
  computed: {
    headerStyle() {
      let width = 'calc(100% - 20px)'
      return { width: width, marginLeft: !this.showSelect ? '14px' : '' }
    },
    finalList() {
      return this.listData.slice(this.startIndex, this.endIndex) // 展示的数据
    },
  },
  mounted() {
    this.updateHeight()
  },
  methods: {
    checkBoxChange(e) {
      this.emitRowSelect()
    },
    updateHeight() {
      this.$refs.viewPort.style.height = this.$refs.list.style.height = this.rowHeight * this.viewCount + 'px' // 视口高度动态赋值
      this.$refs.scrollBar.style.height = this.listData.length * this.rowHeight + 'px' // 滚动条高度动态赋值
    },
    emitRowSelect() {
      setTimeout(() => {
        this.$emit(
          'rowSelect',
          this.listData.filter((i) => i.check),
        )
      }, 100)
    },
    handleScroll() {
      this.startIndex = Math.round(this.$refs.viewPort.scrollTop / this.rowHeight) // 开始索引
      this.endIndex = this.startIndex + this.viewCount // 结束索引
      this.$refs.list.style.transform = `translateY(${this.startIndex * this.rowHeight}px)` // 向下平移
    },
  },
}
</script>

<style scoped lang="scss">
.header {
  font-size: 13px;
  background-color: #f8f8f9;
  border-bottom: 1px solid #dfe6ec;
  font-weight: 600;
  display: flex;
  align-items: center;
  height: 26px;
  &-wrapper {
    display: flex;
    &_item {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
      text-align: center;
    }
  }
}
.viewPort {
  width: 100%;
  overflow-y: auto;
  position: relative;
  .list {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    .row {
      height: var(--scroll-eight);
      width: 100%;
      display: flex;
      align-items: center;
      border-bottom: 1px solid #eee;
      .prop {
        flex: 1;
        text-align: center;
        white-space: nowrap;
      }
    }
  }
}
</style>
